home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / cmds / gdb.new / sprite / gdb / mips-tdep.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-09-06  |  22.0 KB  |  690 lines

  1. /* Work with core dump and executable files, for GDB on MIPS. 
  2.    This code would be in core.c if it weren't machine-dependent. */
  3.  
  4. /* Low level interface to ptrace, for GDB when running under Unix.
  5.    Copyright (C) 1988, 1989, 1990  Free Software Foundation, Inc.
  6.    Contributed by Alessandro Forin(af@cs.cmu.edu) at CMU
  7.    and by Per Bothner(bothner@cs.wisc.edu) at U.Wisconsin.
  8.  
  9. This file is part of GDB.
  10.  
  11. This program is free software; you can redistribute it and/or modify
  12. it under the terms of the GNU General Public License as published by
  13. the Free Software Foundation; either version 2 of the License, or
  14. (at your option) any later version.
  15.  
  16. This program is distributed in the hope that it will be useful,
  17. but WITHOUT ANY WARRANTY; without even the implied warranty of
  18. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  19. GNU General Public License for more details.
  20.  
  21. You should have received a copy of the GNU General Public License
  22. along with this program; if not, write to the Free Software
  23. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
  24.  
  25. /* FIXME: Can a MIPS porter/tester determine which of these include
  26.    files we still need?   -- gnu@cygnus.com */
  27. #include <stdio.h>
  28. #include <mips/inst.h>
  29. #include "defs.h"
  30. #include "param.h"
  31. #include "frame.h"
  32. #include "inferior.h"
  33. #include "symtab.h"
  34. #include "value.h"
  35. #include "gdbcmd.h"
  36.  
  37. #ifdef USG
  38. #include <sys/types.h>
  39. #endif
  40.  
  41.  
  42. #include <signal.h>
  43. #include <sys/param.h>
  44. #include <sys/dir.h>
  45. #include <sys/ioctl.h>
  46.  
  47.  
  48. #include "gdbcore.h"
  49.  
  50. #ifndef    MIPSMAGIC
  51. #ifdef MIPSEL
  52. #define MIPSMAGIC    MIPSELMAGIC
  53. #else
  54. #define MIPSMAGIC    MIPSEBMAGIC
  55. #endif
  56. #endif
  57.  
  58. #define VM_MIN_ADDRESS (unsigned)0x400000
  59.  
  60. #include <sys/user.h>        /* After a.out.h  */
  61. #include <sys/file.h>
  62. #include <sys/stat.h>
  63.  
  64.  
  65. #define PROC_LOW_ADDR(proc) ((proc)->adr) /* least address */
  66. #define PROC_HIGH_ADDR(proc) ((proc)->pad2) /* upper address bound */
  67. #define PROC_FRAME_OFFSET(proc) ((proc)->framesize)
  68. #define PROC_FRAME_REG(proc) ((proc)->framereg)
  69. #define PROC_REG_MASK(proc) ((proc)->regmask)
  70. #define PROC_FREG_MASK(proc) ((proc)->fregmask)
  71. #define PROC_REG_OFFSET(proc) ((proc)->regoffset)
  72. #define PROC_FREG_OFFSET(proc) ((proc)->fregoffset)
  73. #define PROC_PC_REG(proc) ((proc)->pcreg)
  74. #define PROC_SYMBOL(proc) (*(struct symbol**)&(proc)->isym)
  75. #define _PROC_MAGIC_ 0x0F0F0F0F
  76. #define PROC_DESC_IS_DUMMY(proc) ((proc)->isym == _PROC_MAGIC_)
  77. #define SET_PROC_DESC_IS_DUMMY(proc) ((proc)->isym = _PROC_MAGIC_)
  78.  
  79. struct linked_proc_info
  80. {
  81.   struct mips_extra_func_info info;
  82.   struct linked_proc_info *next;
  83. } * linked_proc_desc_table = NULL;
  84.  
  85.  
  86. #define READ_FRAME_REG(fi, regno) read_next_frame_reg((fi)->next, regno)
  87.  
  88. int
  89. read_next_frame_reg(fi, regno)
  90.      FRAME fi;
  91.      int regno;
  92. {
  93. #define SIGFRAME_BASE   sizeof(struct sigcontext)
  94. #define SIGFRAME_PC_OFF (-SIGFRAME_BASE+ 2*sizeof(int))
  95. #define SIGFRAME_SP_OFF (-SIGFRAME_BASE+32*sizeof(int))
  96. #define SIGFRAME_RA_OFF (-SIGFRAME_BASE+34*sizeof(int))
  97.   for (; fi; fi = fi->next)
  98.       if (in_sigtramp(fi->pc, 0)) {
  99.       /* No idea if this code works. --PB. */
  100.       int offset;
  101.       if (regno == PC_REGNUM) offset = SIGFRAME_PC_OFF;
  102.       else if (regno == RA_REGNUM) offset = SIGFRAME_RA_OFF;
  103.       else if (regno == SP_REGNUM) offset = SIGFRAME_SP_OFF;
  104.       else return 0;
  105.       return read_memory_integer(fi->frame + offset, 4);
  106.       }
  107.       else if (regno == SP_REGNUM) return fi->frame;
  108.       else if (fi->saved_regs->regs[regno])
  109.     return read_memory_integer(fi->saved_regs->regs[regno], 4);
  110.   return read_register(regno);
  111. }
  112.  
  113. int
  114. mips_frame_saved_pc(frame)
  115.      FRAME frame;
  116. {
  117.   mips_extra_func_info_t proc_desc = (mips_extra_func_info_t)frame->proc_desc;
  118.   int pcreg = proc_desc ? PROC_PC_REG(proc_desc) : RA_REGNUM;
  119.   if (proc_desc && PROC_DESC_IS_DUMMY(proc_desc))
  120.       return read_memory_integer(frame->frame - 4, 4);
  121. #if 0
  122.   /* If in the procedure prologue, RA_REGNUM might not have been saved yet.
  123.    * Assume non-leaf functions start with:
  124.    *    addiu $sp,$sp,-frame_size
  125.    *    sw $ra,ra_offset($sp)
  126.    * This if the pc is pointing at either of these instructions,
  127.    * then $ra hasn't been trashed.
  128.    * If the pc has advanced beyond these two instructions,
  129.    * then $ra has been saved.
  130.    * critical, and much more complex. Handling $ra is enough to get
  131.    * a stack trace, but some register values with be wrong.
  132.    */
  133.   if (frame->proc_desc && frame->pc < PROC_LOW_ADDR(proc_desc) + 8)
  134.       return read_register(pcreg);
  135. #endif
  136.   return read_next_frame_reg(frame, pcreg);
  137. }
  138.  
  139. static struct mips_extra_func_info temp_proc_desc;
  140. static struct frame_saved_regs temp_saved_regs;
  141.  
  142. CORE_ADDR heuristic_proc_start(pc)
  143.     CORE_ADDR pc;
  144. {
  145.  
  146.     CORE_ADDR start_pc = pc;
  147.     CORE_ADDR fence = start_pc - 10000;
  148.     if (fence < VM_MIN_ADDRESS) fence = VM_MIN_ADDRESS;
  149.     /* search back for previous return */
  150.     for (start_pc -= 4; ; start_pc -= 4)
  151.     if (start_pc < fence) return 0; 
  152.     else if (ABOUT_TO_RETURN(start_pc))
  153.         break;
  154.  
  155.     start_pc += 8; /* skip return, and its delay slot */
  156. #if 0
  157.     /* skip nops (usually 1) 0 - is this */
  158.     while (start_pc < pc && read_memory_integer (start_pc, 4) == 0)
  159.     start_pc += 4;
  160. #endif
  161.     return start_pc;
  162. }
  163.  
  164. mips_extra_func_info_t
  165. heuristic_proc_desc(start_pc, limit_pc, next_frame)
  166.     CORE_ADDR start_pc, limit_pc;
  167.     FRAME next_frame;
  168. {
  169.     CORE_ADDR sp = next_frame ? next_frame->frame : read_register (SP_REGNUM);
  170.     CORE_ADDR cur_pc;
  171.     int frame_size;
  172.     int has_frame_reg = 0;
  173.     int reg30; /* Value of $r30. Used by gcc for frame-pointer */
  174.     unsigned long reg_mask = 0;
  175.  
  176.     if (start_pc == 0) return NULL;
  177.     bzero(&temp_proc_desc, sizeof(temp_proc_desc));
  178.     bzero(&temp_saved_regs, sizeof(struct frame_saved_regs));
  179.     if (start_pc + 200 < limit_pc) limit_pc = start_pc + 200;
  180.   restart:
  181.     frame_size = 0;
  182.     for (cur_pc = start_pc; cur_pc < limit_pc; cur_pc += 4) {
  183.     unsigned long word;
  184.     int status;
  185.  
  186.     status = read_memory_nobpt (cur_pc, &word, 4); 
  187.     if (status) memory_error (status, cur_pc); 
  188.     if ((word & 0xFFFF0000) == 0x27bd0000) /* addiu $sp,$sp,-i */
  189.         frame_size += (-word) & 0xFFFF;
  190.     else if ((word & 0xFFFF0000) == 0x23bd0000) /* addu $sp,$sp,-i */
  191.         frame_size += (-word) & 0xFFFF;
  192.     else if ((word & 0xFFE00000) == 0xafa00000) { /* sw reg,offset($sp) */
  193.         int reg = (word & 0x001F0000) >> 16;
  194.         reg_mask |= 1 << reg;
  195.         temp_saved_regs.regs[reg] = sp + (short)word;
  196.     }
  197.     else if ((word & 0xFFFF0000) == 0x27be0000) { /* addiu $30,$sp,size */
  198.         if ((unsigned short)word != frame_size)
  199.         reg30 = sp + (unsigned short)word;
  200.         else if (!has_frame_reg) {
  201.         int alloca_adjust;
  202.         has_frame_reg = 1;
  203.         reg30 = read_next_frame_reg(next_frame, 30);
  204.         alloca_adjust = reg30 - (sp + (unsigned short)word);
  205.         if (alloca_adjust > 0) {
  206.             /* FP > SP + frame_size. This may be because
  207.             /* of an alloca or somethings similar.
  208.              * Fix sp to "pre-alloca" value, and try again.
  209.              */
  210.             sp += alloca_adjust;
  211.             goto restart;
  212.         }
  213.         }
  214.     }
  215.     else if ((word & 0xFFE00000) == 0xafc00000) { /* sw reg,offset($30) */
  216.         int reg = (word & 0x001F0000) >> 16;
  217.         reg_mask |= 1 << reg;
  218.         temp_saved_regs.regs[reg] = reg30 + (short)word;
  219.     }
  220.     }
  221.     if (has_frame_reg) {
  222.     PROC_FRAME_REG(&temp_proc_desc) = 30;
  223.     PROC_FRAME_OFFSET(&temp_proc_desc) = 0;
  224.     }
  225.     else {
  226.     PROC_FRAME_REG(&temp_proc_desc) = SP_REGNUM;
  227.     PROC_FRAME_OFFSET(&temp_proc_desc) = frame_size;
  228.     }
  229.     PROC_REG_MASK(&temp_proc_desc) = reg_mask;
  230.     PROC_PC_REG(&temp_proc_desc) = RA_REGNUM;
  231.     return &temp_proc_desc;
  232. }
  233.  
  234. mips_extra_func_info_t
  235. find_proc_desc(pc, next_frame)
  236.     CORE_ADDR pc;
  237.     FRAME next_frame;
  238. {
  239.   mips_extra_func_info_t proc_desc;
  240.   extern struct block *block_for_pc();
  241.   struct block   *b = block_for_pc(pc);
  242.  
  243.   struct symbol *sym =
  244.       b ? lookup_symbol(".gdbinfo.", b, LABEL_NAMESPACE, 0, NULL) : NULL;
  245.   if (sym != NULL)
  246.     {
  247.     /* IF this is the topmost frame AND
  248.      * (this proc does not have debugging information OR
  249.      * the PC is in the procedure prologue)
  250.      * THEN create a "hueristic" proc_desc (by analyzing
  251.      * the actual code) to replace the "official" proc_desc.
  252.      */
  253.     proc_desc = (struct mips_extra_func_info *)sym->value.value;
  254.     if (next_frame == NULL) {
  255.         struct symtab_and_line val;
  256.         struct symbol *proc_symbol =
  257.         PROC_DESC_IS_DUMMY(proc_desc) ? 0 : PROC_SYMBOL(proc_desc);
  258.         if (proc_symbol) {
  259.         val = find_pc_line (BLOCK_START
  260.                     (SYMBOL_BLOCK_VALUE(proc_symbol)),
  261.                     0);
  262.         val.pc = val.end ? val.end : pc;
  263.         }
  264.         if (!proc_symbol || pc < val.pc) {
  265.         mips_extra_func_info_t found_heuristic =
  266.             heuristic_proc_desc(PROC_LOW_ADDR(proc_desc),
  267.                     pc, next_frame);
  268.         if (found_heuristic) proc_desc = found_heuristic;
  269.         }
  270.     }
  271.     }
  272.   else
  273.     {
  274.       register struct linked_proc_info *link;
  275.       for (link = linked_proc_desc_table; link; link = link->next)
  276.       if (PROC_LOW_ADDR(&link->info) <= pc
  277.           && PROC_HIGH_ADDR(&link->info) > pc)
  278.           return &link->info;
  279.       proc_desc =
  280.       heuristic_proc_desc(heuristic_proc_start(pc), pc, next_frame);
  281.     }
  282.   return proc_desc;
  283. }
  284.  
  285. mips_extra_func_info_t cached_proc_desc;
  286.  
  287. FRAME_ADDR mips_frame_chain(frame)
  288.     FRAME frame;
  289. {
  290.     extern CORE_ADDR startup_file_start;    /* From blockframe.c */
  291.     mips_extra_func_info_t proc_desc;
  292.     CORE_ADDR saved_pc = FRAME_SAVED_PC(frame);
  293.     if (startup_file_start)
  294.       { /* has at least the __start symbol */
  295.     if (saved_pc == 0 || !outside_startup_file (saved_pc)) return 0;
  296.       }
  297.     else
  298.       { /* This hack depends on the internals of __start. */
  299.     /* We also assume the breakpoints are *not* inserted */
  300.         if (saved_pc == 0
  301.         || read_memory_integer (saved_pc + 8, 4) & 0xFC00003F == 0xD)
  302.         return 0;  /* break */
  303.       }
  304.     proc_desc = find_proc_desc(saved_pc, frame);
  305.     if (!proc_desc) return 0;
  306.     cached_proc_desc = proc_desc;
  307.     return read_next_frame_reg(frame, PROC_FRAME_REG(proc_desc))
  308.     + PROC_FRAME_OFFSET(proc_desc);
  309. }
  310.  
  311. void
  312. init_extra_frame_info(fci)
  313.      struct frame_info *fci;
  314. {
  315.   extern struct obstack frame_cache_obstack;
  316.   /* Use proc_desc calculated in frame_chain */
  317.   mips_extra_func_info_t proc_desc = fci->next ? cached_proc_desc :
  318.       find_proc_desc(fci->pc, fci->next);
  319.   fci->saved_regs = (struct frame_saved_regs*)
  320.     obstack_alloc (&frame_cache_obstack, sizeof(struct frame_saved_regs));
  321.   bzero(fci->saved_regs, sizeof(struct frame_saved_regs));
  322.   fci->proc_desc =
  323.       proc_desc == &temp_proc_desc ? (char*)NULL : (char*)proc_desc;
  324.   if (proc_desc)
  325.     {
  326.       int ireg;
  327.       CORE_ADDR reg_position;
  328.       unsigned long mask;
  329.       /* r0 bit means kernel trap */
  330.       int kernel_trap = PROC_REG_MASK(proc_desc) & 1;
  331.  
  332.       /* Fixup frame-pointer - only needed for top frame */
  333.       /* This may not be quite right, if procedure has a real frame register */
  334.       if (fci->pc == PROC_LOW_ADDR(proc_desc))
  335.       fci->frame = read_register (SP_REGNUM);
  336.       else
  337.       fci->frame = READ_FRAME_REG(fci, PROC_FRAME_REG(proc_desc))
  338.           + PROC_FRAME_OFFSET(proc_desc);
  339.  
  340.       if (proc_desc == &temp_proc_desc)
  341.       *fci->saved_regs = temp_saved_regs;
  342.       else
  343.       {
  344.       /* find which general-purpose registers were saved */
  345.       reg_position = fci->frame + PROC_REG_OFFSET(proc_desc);
  346.       mask = kernel_trap ? 0xFFFFFFFF : PROC_REG_MASK(proc_desc);
  347.       for (ireg= 31; mask; --ireg, mask <<= 1)
  348.           if (mask & 0x80000000)
  349.           {
  350.           fci->saved_regs->regs[ireg] = reg_position;
  351.           reg_position -= 4;
  352.           }
  353.       /* find which floating-point registers were saved */
  354.       reg_position = fci->frame + PROC_FREG_OFFSET(proc_desc);
  355.       /* The freg_offset points to where the first *double* register is saved.
  356.        * So skip to the high-order word. */
  357.       reg_position += 4;
  358.       mask = kernel_trap ? 0xFFFFFFFF : PROC_FREG_MASK(proc_desc);
  359.       for (ireg = 31; mask; --ireg, mask <<= 1)
  360.           if (mask & 0x80000000)
  361.           {
  362.           fci->saved_regs->regs[32+ireg] = reg_position;
  363.           reg_position -= 4;
  364.           }
  365.       }
  366.  
  367.       /* hack: if argument regs are saved, guess these contain args */
  368.       if ((PROC_REG_MASK(proc_desc) & 0xF0) == 0) fci->num_args = -1;
  369.       else if ((PROC_REG_MASK(proc_desc) & 0x80) == 0) fci->num_args = 4;
  370.       else if ((PROC_REG_MASK(proc_desc) & 0x40) == 0) fci->num_args = 3;
  371.       else if ((PROC_REG_MASK(proc_desc) & 0x20) == 0) fci->num_args = 2;
  372.       else if ((PROC_REG_MASK(proc_desc) & 0x10) == 0) fci->num_args = 1;
  373.  
  374.       fci->saved_regs->regs[PC_REGNUM] = fci->saved_regs->regs[RA_REGNUM];
  375.     }
  376.   if (fci->next == 0)
  377.       supply_register(FP_REGNUM, &fci->frame);
  378. }
  379.  
  380.  
  381. CORE_ADDR mips_push_arguments(nargs, args, sp, struct_return, struct_addr)
  382.   int nargs;
  383.   value *args;
  384.   CORE_ADDR sp;
  385.   int struct_return;
  386.   CORE_ADDR struct_addr;
  387. {
  388.   CORE_ADDR buf;
  389.   register i;
  390.   int accumulate_size = struct_return ? 4 : 0;
  391.   struct mips_arg { char *contents; int len; int offset; };
  392.   struct mips_arg *mips_args =
  393.       (struct mips_arg*)alloca(nargs * sizeof(struct mips_arg));
  394.   register struct mips_arg *m_arg;
  395.   for (i = 0, m_arg = mips_args; i < nargs; i++, m_arg++) {
  396.     extern value value_arg_coerce();
  397.     value arg = value_arg_coerce (args[i]);
  398.     m_arg->len = TYPE_LENGTH (VALUE_TYPE (arg));
  399.     /* This entire mips-specific routine is because doubles must be aligned
  400.      * on 8-byte boundaries. It still isn't quite right, because MIPS decided
  401.      * to align 'struct {int a, b}' on 4-byte boundaries (even though this
  402.      * breaks their varargs implementation...). A correct solution
  403.      * requires an simulation of gcc's 'alignof' (and use of 'alignof'
  404.      * in stdarg.h/varargs.h).
  405.      */
  406.     if (m_arg->len > 4) accumulate_size = (accumulate_size + 7) & -8;
  407.     m_arg->offset = accumulate_size;
  408.     accumulate_size = (accumulate_size + m_arg->len + 3) & -4;
  409.     m_arg->contents = VALUE_CONTENTS(arg);
  410.   }
  411.   accumulate_size = (accumulate_size + 7) & (-8);
  412.   if (accumulate_size < 16) accumulate_size = 16; 
  413.   sp -= accumulate_size;
  414.   for (i = nargs; m_arg--, --i >= 0; )
  415.     write_memory(sp + m_arg->offset, m_arg->contents, m_arg->len);
  416.   if (struct_return) {
  417.     buf = struct_addr;
  418.     write_memory(sp, &buf, sizeof(CORE_ADDR));
  419. }
  420.   return sp;
  421. }
  422.  
  423. /* MASK(i,j) == (1<<i) + (1<<(i+1)) + ... + (1<<j)). Assume i<=j<31. */
  424. #define MASK(i,j) ((1 << (j)+1)-1 ^ (1 << (i))-1)
  425.  
  426. void
  427. mips_push_dummy_frame()
  428. {
  429.   int ireg;
  430.   struct linked_proc_info *link = (struct linked_proc_info*)
  431.       xmalloc(sizeof(struct linked_proc_info));
  432.   mips_extra_func_info_t proc_desc = &link->info;
  433.   CORE_ADDR sp = read_register (SP_REGNUM);
  434.   CORE_ADDR save_address;
  435.   REGISTER_TYPE buffer;
  436.   link->next = linked_proc_desc_table;
  437.   linked_proc_desc_table = link;
  438. #define PUSH_FP_REGNUM 16 /* must be a register preserved across calls */
  439. #define GEN_REG_SAVE_MASK MASK(1,16)|MASK(24,28)|(1<<31)
  440. #define GEN_REG_SAVE_COUNT 22
  441. #define FLOAT_REG_SAVE_MASK MASK(0,19)
  442. #define FLOAT_REG_SAVE_COUNT 20
  443. #define SPECIAL_REG_SAVE_COUNT 4
  444.   /*
  445.    * The registers we must save are all those not preserved across
  446.    * procedure calls. Dest_Reg (see tm-mips.h) must also be saved.
  447.    * In addition, we must save the PC, and PUSH_FP_REGNUM.
  448.    * (Ideally, we should also save MDLO/-HI and FP Control/Status reg.)
  449.    *
  450.    * Dummy frame layout:
  451.    *  (high memory)
  452.    *     Saved PC
  453.    *    Saved MMHI, MMLO, FPC_CSR
  454.    *    Saved R31
  455.    *    Saved R28
  456.    *    ...
  457.    *    Saved R1
  458.    *    Saved D18 (i.e. F19, F18)
  459.    *    ...
  460.    *    Saved D0 (i.e. F1, F0)
  461.    *    CALL_DUMMY (subroutine stub; see m-mips.h)
  462.    *    Parameter build area (not yet implemented)
  463.    *  (low memory)
  464.    */
  465.   PROC_REG_MASK(proc_desc) = GEN_REG_SAVE_MASK;
  466.   PROC_FREG_MASK(proc_desc) = FLOAT_REG_SAVE_MASK;
  467.   PROC_REG_OFFSET(proc_desc) = /* offset of (Saved R31) from FP */
  468.       -sizeof(long) - 4 * SPECIAL_REG_SAVE_COUNT;
  469.   PROC_FREG_OFFSET(proc_desc) = /* offset of (Saved D18) from FP */
  470.       -sizeof(double) - 4 * (SPECIAL_REG_SAVE_COUNT + GEN_REG_SAVE_COUNT);
  471.   /* save general registers */
  472.   save_address = sp + PROC_REG_OFFSET(proc_desc);
  473.   for (ireg = 32; --ireg >= 0; )
  474.     if (PROC_REG_MASK(proc_desc) & (1 << ireg))
  475.       {
  476.     buffer = read_register (ireg);
  477.     write_memory (save_address, &buffer, sizeof(REGISTER_TYPE));
  478.     save_address -= 4;
  479.       }
  480.   /* save floating-points registers */
  481.   save_address = sp + PROC_FREG_OFFSET(proc_desc);
  482.   for (ireg = 32; --ireg >= 0; )
  483.     if (PROC_FREG_MASK(proc_desc) & (1 << ireg))
  484.       {
  485.     buffer = read_register (ireg);
  486.     write_memory (save_address, &buffer, 4);
  487.     save_address -= 4;
  488.       }
  489.   write_register (PUSH_FP_REGNUM, sp);
  490.   PROC_FRAME_REG(proc_desc) = PUSH_FP_REGNUM;
  491.   PROC_FRAME_OFFSET(proc_desc) = 0;
  492.   buffer = read_register (PC_REGNUM);
  493.   write_memory (sp - 4, &buffer, sizeof(REGISTER_TYPE));
  494.   buffer = read_register (HI_REGNUM);
  495.   write_memory (sp - 8, &buffer, sizeof(REGISTER_TYPE));
  496.   buffer = read_register (LO_REGNUM);
  497.   write_memory (sp - 12, &buffer, sizeof(REGISTER_TYPE));
  498.   buffer = read_register (FCRCS_REGNUM);
  499.   write_memory (sp - 16, &buffer, sizeof(REGISTER_TYPE));
  500.   sp -= 4 * (GEN_REG_SAVE_COUNT+FLOAT_REG_SAVE_COUNT+SPECIAL_REG_SAVE_COUNT);
  501.   write_register (SP_REGNUM, sp);
  502.   PROC_LOW_ADDR(proc_desc) = sp - CALL_DUMMY_SIZE + CALL_DUMMY_START_OFFSET;
  503.   PROC_HIGH_ADDR(proc_desc) = sp;
  504.   SET_PROC_DESC_IS_DUMMY(proc_desc);
  505.   PROC_PC_REG(proc_desc) = RA_REGNUM;
  506. }
  507.  
  508. void
  509. mips_pop_frame()
  510. { register int regnum;
  511.   FRAME frame = get_current_frame ();
  512.   CORE_ADDR new_sp = frame->frame;
  513.   mips_extra_func_info_t proc_desc = (mips_extra_func_info_t)frame->proc_desc;
  514.   if (PROC_DESC_IS_DUMMY(proc_desc))
  515.     {
  516.       struct linked_proc_info **ptr = &linked_proc_desc_table;;
  517.       for (; &ptr[0]->info != proc_desc; ptr = &ptr[0]->next )
  518.       if (ptr[0] == NULL) abort();
  519.       *ptr = ptr[0]->next;
  520.       free (ptr[0]);
  521.       write_register (HI_REGNUM, read_memory_integer(new_sp - 8, 4));
  522.       write_register (LO_REGNUM, read_memory_integer(new_sp - 12, 4));
  523.       write_register (FCRCS_REGNUM, read_memory_integer(new_sp - 16, 4));
  524.     }
  525.   write_register (PC_REGNUM, FRAME_SAVED_PC(frame));
  526.   if (frame->proc_desc) {
  527.     for (regnum = 32; --regnum >= 0; )
  528.       if (PROC_REG_MASK(proc_desc) & (1 << regnum))
  529.     write_register (regnum,
  530.           read_memory_integer (frame->saved_regs->regs[regnum], 4));
  531.     for (regnum = 64; --regnum >= 32; )
  532.       if (PROC_FREG_MASK(proc_desc) & (1 << regnum))
  533.     write_register (regnum,
  534.           read_memory_integer (frame->saved_regs->regs[regnum], 4));
  535.   }
  536.   write_register (SP_REGNUM, new_sp);
  537.   flush_cached_frames ();
  538.   set_current_frame (create_new_frame (new_sp, read_pc ()));
  539. }
  540.  
  541. static
  542. mips_print_register(regnum, all)
  543.      int regnum, all;
  544. {
  545.       unsigned char raw_buffer[8];
  546.       REGISTER_TYPE val;
  547.  
  548.       read_relative_register_raw_bytes (regnum, raw_buffer);
  549.  
  550.       if (!(regnum & 1) && regnum >= FP0_REGNUM && regnum < FP0_REGNUM+32) {
  551.       read_relative_register_raw_bytes (regnum+1, raw_buffer+4);
  552.       printf_filtered ("(d%d: ", regnum&31);
  553.       val_print (builtin_type_double, raw_buffer, 0,
  554.              stdout, 0, 1, 0, Val_pretty_default);
  555.       printf_filtered ("); ", regnum&31);
  556.       }
  557.       fputs_filtered (reg_names[regnum], stdout);
  558. #ifndef NUMERIC_REG_NAMES
  559.       if (regnum < 32)
  560.       printf_filtered ("(r%d): ", regnum);
  561.       else
  562. #endif
  563.       printf_filtered (": ");
  564.  
  565.       /* If virtual format is floating, print it that way.  */
  566.       if (TYPE_CODE (REGISTER_VIRTUAL_TYPE (regnum)) == TYPE_CODE_FLT
  567.       && ! INVALID_FLOAT (raw_buffer, REGISTER_VIRTUAL_SIZE(regnum))) {
  568.       val_print (REGISTER_VIRTUAL_TYPE (regnum), raw_buffer, 0,
  569.              stdout, 0, 1, 0, Val_pretty_default);
  570.       }
  571.       /* Else print as integer in hex.  */
  572.       else
  573.     {
  574.       long val;
  575.  
  576.       bcopy (raw_buffer, &val, sizeof (long));
  577.       if (val == 0)
  578.         printf_filtered ("0");
  579.       else if (all)
  580.         printf_filtered ("0x%x", val);
  581.       else
  582.         printf_filtered ("0x%x=%d", val, val);
  583.     }
  584. }
  585.  
  586. /* Replacement for generic do_registers_info.  */
  587. mips_do_registers_info (regnum, fpregs)
  588.      int regnum;
  589.      int fpregs;
  590. {
  591.   if (regnum != -1) {
  592.       mips_print_register (regnum, 0);
  593.       printf_filtered ("\n");
  594.   }
  595.   else {
  596.       for (regnum = 0; regnum < NUM_REGS; ) {
  597.       if ((!fpregs) && regnum >= FP0_REGNUM && regnum <= FCRIR_REGNUM) {
  598.         regnum++;
  599.         continue;
  600.       }
  601.       mips_print_register (regnum, 1);
  602.       regnum++;
  603.       if ((regnum & 3) == 0 || regnum == NUM_REGS)
  604.           printf_filtered (";\n");
  605.       else
  606.           printf_filtered ("; ");
  607.       }
  608.   }
  609. }
  610. /* Return number of args passed to a frame. described by FIP.
  611.    Can return -1, meaning no way to tell.  */
  612.  
  613. mips_frame_num_args(fip)
  614.     FRAME fip;
  615. {
  616. #if 0
  617.     struct chain_info_t *p;
  618.  
  619.     p = mips_find_cached_frame(FRAME_FP(fip));
  620.     if (p->valid)
  621.         return p->the_info.numargs;
  622. #endif
  623.     return -1;
  624. }
  625.  
  626.  
  627. /* Bad floats: Returns 0 if P points to a valid IEEE floating point number,
  628.    1 if P points to a denormalized number or a NaN. LEN says whether this is
  629.    a single-precision or double-precision float */
  630. #define SINGLE_EXP_BITS  8
  631. #define DOUBLE_EXP_BITS 11
  632. int
  633. isa_NAN(p, len)
  634.      int *p, len;
  635. {
  636.   int exponent;
  637.   if (len == 4)
  638.     {
  639.       exponent = *p;
  640.       exponent = exponent << 1 >> (32 - SINGLE_EXP_BITS - 1);
  641.       return ((exponent == -1) || (! exponent && *p));
  642.     }
  643.   else if (len == 8)
  644.     {
  645.       exponent = *(p+1);
  646.       exponent = exponent << 1 >> (32 - DOUBLE_EXP_BITS - 1);
  647.       return ((exponent == -1) || (! exponent && *p * *(p+1)));
  648.     }
  649.   else return 1;
  650. }
  651.  
  652. /* To skip prologues, I use this predicate. Returns either PC
  653.    itself if the code at PC does not look like a function prologue,
  654.    PC+4 if it does (our caller does not need anything more fancy). */
  655.  
  656. CORE_ADDR mips_skip_prologue(pc)
  657.      CORE_ADDR pc;
  658. {
  659.     struct symbol *f;
  660.     struct block *b;
  661.     unsigned long inst;
  662.  
  663.     /* For -g modules and most functions anyways the
  664.        first instruction adjusts the stack. */
  665.     inst = read_memory_integer(pc, 4);
  666.     if ((inst & 0xffff0000) == 0x27bd0000)
  667.     return pc + 4;
  668.  
  669.     /* Well, it looks like a frameless. Let's make sure.
  670.        Note that we are not called on the current PC,
  671.        but on the function`s start PC, and I have definitely
  672.        seen optimized code that adjusts the SP quite later */
  673.     b = block_for_pc(pc);
  674.     if (!b) return pc;
  675.  
  676.     f = lookup_symbol(".gdbinfo.", b, LABEL_NAMESPACE, 0, NULL);
  677.     if (!f) return pc;
  678.     /* Ideally, I would like to use the adjusted info
  679.        from mips_frame_info(), but for all practical
  680.        purposes it will not matter (and it would require
  681.        a different definition of SKIP_PROLOGUE())
  682.  
  683.        Actually, it would not hurt to skip the storing
  684.        of arguments on the stack as well. */
  685.     if (((struct mips_extra_func_info *)f->value.value)->framesize)
  686.     return pc + 4;
  687.  
  688.     return pc;
  689. }
  690.